/**
 * 
 */
package com.zte.claa.inficombo.csa.app.service.message.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.annotation.PreDestroy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;
import com.zte.claa.inficombo.csa.app.service.message.MessageSubscriber;
import com.zte.claa.inficombo.csa.app.util.ClassUtils;

/**
 * @author 0283000138
 *
 */
@Component
public class MessageSubscriberManager implements ApplicationContextAware {

	@Autowired
	private RedisMessageListenerContainer listenerContainer;
	
	private List<MessageListener> listeners = new ArrayList<>();
	
	private Logger logger = LoggerFactory.getLogger(this.getClass().getName());
	
	@Override
	public void setApplicationContext(ApplicationContext context) throws BeansException {
		init(context);
	}
	
	@PreDestroy
	public void destroy() {
		for (MessageListener listener: listeners){
			try {
				listenerContainer.removeMessageListener(listener);
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
			}
		}
	}
	
	private void init(ApplicationContext context){
		Set<Class<?>> classes = ClassUtils.getClasses();
		for (Class<?> cls : classes){
			MessageSubscriber subsciber = cls.getAnnotation(MessageSubscriber.class);
			if (subsciber == null){
				continue;
			}
			
			Object object = context.getBean(cls);
			if (object == null || ! (object instanceof MessageListener)){
				continue;
			}
			
			MessageListener listener = (MessageListener)object;
			if (subsciber.pattern()){
				listenerContainer.addMessageListener(listener, new PatternTopic(subsciber.topic().trim()));
				logger.info("register message listener class:{}, pattern topic:{}", listener.getClass().getName(), subsciber.topic());
			}
			else{
				listenerContainer.addMessageListener(listener, new ChannelTopic(subsciber.topic().trim()));
				logger.info("register message listener class:{}, channel topic:{}", listener.getClass().getName(), subsciber.topic());
			}
			listeners.add(listener);
		}
	}

}
